{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Overview of model\n",
    "\n",
    "The model we'll start with is based on [Hastie and Lee](https://web.stanford.edu/~hastie/Papers/structmgm.pdf). It fits a certain type of \n",
    "*undirected* graphical model to a sample of random variables of mixed type (discrete or continuous).\n",
    "\n",
    "It has the advantage that it also selects which *interactions* amongst the variables seem most relevant.\n",
    "\n",
    "Our data is\n",
    "$$\n",
    "X = \\begin{pmatrix} X_1 \\\\ X_2 \\\\ \\vdots \\\\ X_n\n",
    "\\end{pmatrix}\n",
    "$$\n",
    "and each sample $X_i$ is of mixed type -- in `numpy / pandas` terms we can think of it having a `dtype` with some `np.float` fields as well as some `pandas.Categotical` fields.\n",
    "We think of having $p$ different variables so we can talk about $X_{ij}, 1 \\leq i \\leq n, 1 \\leq j \\leq p$."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Special case: binary random variables\n",
    "\n",
    "In this case $X_i \\in \\{0,1\\}^p$. The model here is a generalization of the Ising model. That is, each row is like a realization of an Ising model so we have a sample of realizations of Ising models.\n",
    "\n",
    "The model is parameterized here by a $p \\times p$ symmetric matrix $\\Sigma$\n",
    "and\n",
    "$$\n",
    "P_{\\Theta}(X_i=x_i) \\propto \\exp\\left(\\sum_{j,k} x_{i,j} x_{i,k} \\Theta_{jk} \\right).\n",
    "$$\n",
    "\n",
    "Classical Ising models have a fixed graph, say with adjacency matrix $A$ and perhaps two parameters $(\\theta_1, \\theta_2)$: one for interaction and one affecting the overall mean (external field? not sure, not a physicist). In these models\n",
    "$$\n",
    "P_{(\\theta_1, \\theta_2)}(X_i=x) \\propto \\exp \\left(\\theta_1 \\sum_j x_j + \\theta_2 \\sum_{j, k} x_j x_k A_{jk}\\right)\n",
    "$$\n",
    "so we can think of this having a $\\Theta$ with $\\theta_1$ on the diagonal and $\\theta_2/2$ off the diagonal.\n",
    "\n",
    "This model therefore has a parameter for *each edge*. Edges are selected by putting a penalty on each edge, i.e. an $\\ell_1$ penalty perhaps leaving the mean terms unpenalized:\n",
    "$$\n",
    "{\\cal P}(\\Theta) = \\lambda \\sum_{(j,k): j \\neq k} |\\Theta_{jk}|.\n",
    "$$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Psuedolikelihood\n",
    "\n",
    "To fit this model is complicated -- it is expensive to normalize the $\\propto$ in the likelihood so people, dating back to Besag in the 80s have used pseudolikelihood as the objective.\n",
    "\n",
    "This objective is the sum of all the conditional likelihoods for one of the variables given all the others. E.g. in our Ising model here, if we *knew* $\\Sigma$ then for any $X_{i,j}$ we know that $X_{i,j}$ is Bernoulli and given $X_{i,k}, k \\neq j$ we can work out the probability it is 1 or 0 based on $\\Sigma$. This is effectively the likelihood for a logistic regression. There is therefore a likelihood for each column $j$\n",
    "$$\n",
    "\\ell_j(\\Theta; X[:,j] | X[:,k], k \\neq j)\n",
    "$$\n",
    "and the pseudo-likelihood (sum of conditional negative log-likelihoods) is\n",
    "$$\n",
    "\\Theta \\mapsto \\sum_{j=1}^p \\ell_j(\\Theta; X[:,j] | X[:,k], k \\neq j).\n",
    "$$\n",
    "\n",
    "The penalized *pseudolikelihood* is \n",
    "$$\n",
    "\\Theta \\mapsto \\left[\\sum_{j=1}^p \\ell_j(\\Theta; X[:,j] | X[:,k], k \\neq j)\\right] + {\\cal P}(\\Theta).\n",
    "$$\n",
    "\n",
    "This is an objective we can minimize as a function of $\\Theta$. For large enough values of $\\lambda$ the minimize, $\\Theta$ will be sparse off-diagonal. This is the *undirected* graph selection."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Special case: all continuous\n",
    "\n",
    "When each feature is continuous, a common model for the distribution\n",
    "would be Gaussian. This can be parameterized in terms of sufficient\n",
    "statistics $X$ and $XX^T$ with natural parameters $\\alpha$ and\n",
    "$\\Theta$, say. So, the density can be written as $$\n",
    "P_{\\alpha,\\Theta}(X_i=x) \\propto \\exp \\left(\\alpha^Tx +\n",
    "\\text{Tr}(\\Theta xx^T) \\right).$$ \n",
    "This is of course the normal\n",
    "family but parametrized slightly differently.\n",
    "\n",
    "This is quite similar to the binary case (in the binary case we could\n",
    "suck the $\\alpha$ into the diagonal of $\\Theta$) but this doesn't work in the Gaussian case.\n",
    "\n",
    "In this case, for one of the columns $X[:,j]$ there is a\n",
    "pseudo-likelihood corresponding to predicting $X[:,j]$ as a function\n",
    "of $X[:,k], k \\neq j$. Each term in the this pseudo-likelihood looks\n",
    "like a linear regression loss function. Summing these terms gives a\n",
    "pseudo-likelihood that could be used to fit the *graphical LASSO*\n",
    "(e.g. `glasso` in `R`).\n",
    "\n",
    "For Gaussians we need to introduce a separate scale parameter in the optimization.\n",
    "Call these $\\alpha$. Enforcing each $\\Theta[j,j]$ block to be 0, our $j$-th pseudolikelihood\n",
    "for a Gaussian is a normalized version of the density\n",
    "$$\n",
    "x_j \\mapsto \\exp\\left(x_j \\cdot \\left(\\sum_{k:k \\neq j} \\Theta[k,j] x_k\\right) - \\alpha_j x_j^2 \\right). \n",
    "$$\n",
    "The normalizing constant is\n",
    "$$\n",
    "\\sqrt{2 \\pi /\\alpha_j} \\exp\\left( \\frac{1}{2 \\alpha_j} (\\Theta[j]^Tx)^2 \\right)\n",
    "$$\n",
    "so the likelihood for a continuous feature is\n",
    "$$\n",
    "(\\Theta[j], \\alpha_j) \\mapsto \\frac{1}{\\sqrt{2\\pi/\\alpha_j}} \\exp\\left(-\\frac{\\alpha_j}{2} (\\Theta[j]x - x_j)^2 \\right)\n",
    "$$\n",
    "where we have used the convention that $\\Theta[j,j]=0$.\n",
    "\n",
    "Taking negative logs yields\n",
    "$$\n",
    "(\\Theta[j], \\alpha_j) \\mapsto - \\frac{1}{2}\\log(\\alpha_j) + \\frac{\\alpha_j}{2}(\\Theta[j]x-x_j)^2\n",
    "$$\n",
    "\n",
    "Stacking rows and summing yields\n",
    "$$\n",
    "(\\Theta[j], \\alpha_j) \\mapsto - \\frac{n}{2}\\log(\\alpha_j) + \\frac{\\alpha_j}{2}\\|\\eta_j-X[:,j]\\|^2_2\n",
    "$$\n",
    "with $\\eta_j = X\\Theta[:,j]$.            \n",
    "\n",
    "In fact, fixing $\\Theta$, we could solve for $\\alpha_j$ but this seems messy."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Putting these together\n",
    "\n",
    "It is now not hard to see how to mix continuous and binary. Each binary `field` has a reference sample space of $\\{0,1\\}$ while each continuous one has a reference sample space $\\mathbb{R}$. Stringing all fields together gives a sample space\n",
    "$$\n",
    "\\{0,1\\}^{j:j \\in {\\cal B}} \\times \\mathbb{R}^{j: j \\in {\\cal C}}\n",
    "$$\n",
    "where ${\\cal B}$ are the binary fields in our `dtype` and ${\\cal C}$ are the floating type fields in our `dtype`. If we had categorical instead of binary then that field's $\\{0,1\\}$ would be replaced by $\\{1, \\dots, N_j\\}$ where $N_j$ is the number of categories for field $j$.\n",
    "\n",
    "We now have a symmetric $p \\times p$ *matrix* $\\Theta$ (it's not really a matrix) where each entry $\\Theta_{jk}$ models the interaction between field $j$ and field $k$ of the `dtype`. When $j$ or $k$ is categorical (including binary) the entry $\\Theta_{jk}$ is really a matrix. Concretely, suppose $N_j=3$ and $N_k=5$ then, if we were to fit a \n",
    "multinomial regression (the analog of logistic for categorical) of $X[:,j]$ on to $X[:,k]$ then there would be a $3 \\times 5$ matrix of parameters in that model. (Note that much software often will set some of these to 0 automatically for identification reasons -- in this model with the penalty it is common not to do this). Anyways, we see that $\\Theta_{jk}$ is really in $\\mathbb{R}^{3 \\times 5}$ and $\\Theta_{kj} = \\Theta_{jk}^T \\in \\mathbb{R}^{5 \\times 3}$.\n",
    "\n",
    "The (or, an) analog of the $\\ell_1$ penalty for the *matrix* $\\Theta_{jk}$ is the Frobenius norm -- this is what the authors propose."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Relation to separate regressions\n",
    "\n",
    "In order to understand the relationships between columns it is tempting to simply regress each $X[:,j]$ onto all the other columns. The total objective in this case would be a sum of negative log-likelihoods and would look a lot like our pseudo-likelihood. The difference is that the pseudo-likelihood assumes symmetry and ties the parameters together this way. The separate regression framework drops this requirement.\n",
    "\n",
    "That is, the total loss for separate regressions is the same as the pseudo-likelihood\n",
    "but the pseudo-likelihood has linear constraints enforcing symmetry of the $\\Theta$ \"matrix\".\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Fitting the model\n",
    "\n",
    "The model can be fit by proximal gradient methods, so we really just have to compute the\n",
    "objective (as a function of $\\Theta$ with $X$ fixed) and its gradient.\n",
    "\n",
    "As each term in the pseudo-likelihood is like a regression (negative log-) likelihood it is enough to have appropriate regression losses for each node.\n",
    "\n",
    "The proximal step is essentially the group LASSO proximal step (though here the parameters are matrices rather than vectors). By appropriate `vec` operations we should be able to use a group LASSO map."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### TODO\n",
    "\n",
    "0. Create a *design matrix* `X` and a dict mapping fields of the dtype to columns. Should include a column of 1s. Continuous features enter as columns unchanged. Categorical features are coded using *full* representation, i.e. for a categorical with $N_j$ levels we want $N_j$ 1-hot columns in the design matrix. Our final $\\Theta$ parameter will have shape $(X.shape[1], X.shape[1])$ and will be symmetric but we will store as regular `ndarray`.\n",
    "\n",
    "1. Create a representation of the pseudo-likelihood that can compute\n",
    "the maps\n",
    "$$\n",
    "\\begin{aligned}\n",
    "\\Theta & \\mapsto \\sum_{j=1}^p \\ell_j\\left(\\Theta; X[:,j] | X[:,k], k \\neq j \\right) \\\\\n",
    "\\Theta & \\mapsto \\nabla_{\\Theta} \\sum_{j=1}^p \\ell_j\\left(\\Theta; X[:,j] | X[:,k], k \\neq j \\right)\n",
    "\\end{aligned}\n",
    "$$\n",
    "Note that $\\ell_j$ depends only on $\\Theta[j]$ and differentiating with respect to\n",
    "a term like $\\Theta[j,k]$ will involve only the losses $\\ell_k$ and $\\ell_j$.\n",
    "\n",
    "2. Make a group LASSO penalty for the $\\Theta$ matrix that sets $\\infty$ penalty on the \"diagonal\" terms $\\Theta[j,j]$.\n",
    "\n",
    "3. We should be able to just write the loss as a sum of saturated losses for each *response* composed with `X.dot(Theta[j])`, i.e.\n",
    "\n",
    "     loss(theta) = sum([s_loss(X.dot(Theta[j])) for s_loss in saturated_losses])\n",
    "\n",
    "4. For a categorical variable with $N_j$ levels `X.dot(Theta[j])` should have shape `(n, N_j)` and this product should effectively zero out any *self* terms in the sum over the\n",
    "$\\sum_j N_j$ in the matrix product. I.e. I am imaging that feature $j$ has been allocated $N_j$ columns in $X$ (the usual 1-hot encoding of multinomials).\n",
    "\n",
    "5. If we can write out the objective with a single `X` matrix, then I think the $\\Theta[j,k]$ gradient will simply look at the `k` rows of the `j` loss plus the `j` rows of the `k` loss."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Toy example\n",
    "\n",
    "Let's make a data frame with 7 features, 2 binary, 2 categorical and 3 continuous. We'll code the binary as multinomial."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(Index(['ground_track', 'lat', 'lon', 'h_li', 's_li', 'q_flag', 's_fg', 'snr',\n",
       "        'h_rb', 'dh_fit_dx', 'b_snow_conf', 'c_flg_asr', 'c_flg_atm', 'msw',\n",
       "        'bsnow_h', 'bsnow_od', 'layer_flag', 'bckgrd', 'e_bckgrd',\n",
       "        'n_fit_photons', 'segment_id', 'w_surface_window_final'],\n",
       "       dtype='object'),\n",
       " (252416, 22))"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import numpy as np, pandas as pd\n",
    "from itertools import product\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "\n",
    "\n",
    "D = pd.read_csv('atl06.csv') # .iloc[:5000]\n",
    "D = D.dropna()\n",
    "del(D['Unnamed: 0'])\n",
    "D.columns, D.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([3.       , 4.4581361])"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def make_onehot(categorical_col):  #TODO: would be more robust to know labels beforehand\n",
    "                                   # e.g. for cross-validation\n",
    "    labels = sorted(np.unique(categorical_col))\n",
    "    return np.equal.outer(np.asarray(categorical_col), labels)\n",
    "\n",
    "def make_design(df, desc):\n",
    "    design = [np.ones((df.shape[0], 1))] # column for intercept\n",
    "    new_desc = [('intercept', None, slice(0, 1))]\n",
    "    idx = 1\n",
    "    for col, dtype in desc:\n",
    "        if dtype in ['binary', 'categorical']:\n",
    "            design_col = make_onehot(df[col])\n",
    "            ncol = design_col.shape[1]\n",
    "            design.append(design_col)\n",
    "            new_desc.append((col, dtype, slice(idx, idx + ncol)))\n",
    "            idx += ncol\n",
    "        elif dtype == 'continuous': # a continuous one\n",
    "            new_desc.append((col, dtype, slice(idx, idx+1)))\n",
    "            design_col = np.asarray(df[col].copy())\n",
    "            # should we standardize?\n",
    "            design_col.shape = (-1,1)\n",
    "            design.append(design_col)\n",
    "            idx += 1\n",
    "    return np.hstack(design), new_desc\n",
    "\n",
    "desc = [('s_li', 'continuous'),\n",
    "        ('q_flag', 'binary'),\n",
    "        ('snr', 'continuous'),\n",
    "        ('h_rb', 'continuous'),\n",
    "        ('dh_fit_dx', 'continuous'),\n",
    "        ('b_snow_conf', 'categorical'),\n",
    "        ('c_flg_asr', 'categorical'),\n",
    "        ('c_flg_atm', 'categorical'),\n",
    "        ('msw', 'categorical' ),\n",
    "        #('bsnow_h', 'continuous'),\n",
    "        #('bsnow_od', 'continuous'),\n",
    "        ('layer_flag', 'binary'),\n",
    "        ('bckgrd', 'continuous'),\n",
    "        ('e_bckgrd', 'continuous'),\n",
    "        ('n_fit_photons', 'continuous'),\n",
    "        ('w_surface_window_final', 'continuous')]\n",
    "desc\n",
    "(np.mean(D['bsnow_od'] == D['bsnow_od'].max()), \n",
    " np.mean(D['bsnow_h'] == D['bsnow_h'].max()))\n",
    "np.percentile(D['w_surface_window_final'], [2,98])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(array([0.0000000e+00, 6.7144660e-09, 1.0892861e-08, ..., 9.3741010e-01,\n",
       "        9.3925035e-01, 9.4173110e-01]),\n",
       " array([3.4386003e-03, 5.2483900e-03, 5.4293690e-03, ..., 4.9964676e+00,\n",
       "        5.0000000e+00, 3.4028235e+38]))"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X, desc2 = make_design(D, desc)\n",
    "#X = X[np.random.choice(np.arange(X.shape[0]), 50000, replace=False)]\n",
    "desc2\n",
    "np.unique(D['snr']), np.unique(D['h_rb'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[(246767, 'continuous'),\n",
       " (2, 'binary'),\n",
       " (6299, 'continuous'),\n",
       " (7268, 'continuous'),\n",
       " (175317, 'continuous'),\n",
       " (8, 'categorical'),\n",
       " (6, 'categorical'),\n",
       " (3, 'categorical'),\n",
       " (4, 'categorical'),\n",
       " (2, 'binary'),\n",
       " (243085, 'continuous'),\n",
       " (243308, 'continuous'),\n",
       " (713, 'continuous'),\n",
       " (3216, 'continuous')]"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "[(len(np.unique(D[c])), t) for c, t, _ in desc2[1:]]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Form saturated losses \n",
    "\n",
    "This will use the `regreg` package: `http://github.com/jonathan-taylor/regreg.git`\n",
    "\n",
    "For `binary` or `categorical` we will use multinomial loss, while for `continuous`\n",
    "we will use the special Gaussian loss described above."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "from regreg.smooth.mglm import multinomial_loglike\n",
    "from regreg.smooth.glm import gaussian_loglike\n",
    "import regreg.api as rr        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(0,\n",
       " array([0.00000000e+00, 4.27455210e+37, 1.48234511e-01, 1.48234511e-01,\n",
       "        5.01065967e-02, 2.71481633e+37, 3.24797455e+37, 1.17049969e-01,\n",
       "        4.79491936e-01, 4.99880513e-01, 1.29609944e-01, 2.40016662e-01,\n",
       "        2.18420378e-01, 9.24887027e-02, 3.79471257e-02, 3.87709290e-02,\n",
       "        4.64835303e-01, 4.99214417e-01, 3.29700907e-01, 1.41454415e-01,\n",
       "        2.48590316e-01, 4.57907820e-01, 4.53777379e-01, 9.53066884e-02,\n",
       "        4.89373218e-01, 2.95966657e-01, 3.68165670e-01, 3.45703179e-01,\n",
       "        2.77489125e-01, 2.77489125e-01, 4.27455210e+37, 4.27455210e+37,\n",
       "        1.57090474e+08, 3.24797455e+37]),\n",
       " array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]))"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.isnan(X[:,4]).sum(), X.std(0), X[:,0][:10]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Combine losses into a smooth objective function"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "def _reshape(G):\n",
    "    if G.ndim == 1:\n",
    "        return G.reshape((-1, 1))\n",
    "    return G\n",
    "\n",
    "class gaussian_loss(rr.smooth_atom):\n",
    "\n",
    "    \"\"\"\n",
    "    This codes up (11) of Lee and Hastie\n",
    "    \"\"\"\n",
    "\n",
    "class full_loss(rr.smooth_atom):\n",
    "    \n",
    "    def __init__(self,\n",
    "                 X,\n",
    "                 desc,\n",
    "                 symmetrize=True,\n",
    "                 coef=1.,\n",
    "                 offset=None,\n",
    "                 quadratic=None,\n",
    "                 case_weights=None,\n",
    "                 initial=None):\n",
    "        \n",
    "        (self.X, \n",
    "         self.symmetrize) = (X.copy(), symmetrize)\n",
    "\n",
    "        # create individual losses\n",
    "        # categorical / binary\n",
    "        # are multinomial\n",
    "\n",
    "        # continuous ones get a special loss\n",
    "        # with unknown covariance\n",
    "        \n",
    "        idx_cont = 0\n",
    "        self.desc = []\n",
    "        self.sum_sq = []\n",
    "        for var, dtype, idx in desc:\n",
    "            if dtype in ['binary', 'categorical']:\n",
    "                response = self.X[:,idx]\n",
    "                self.desc.append((var, dtype, idx,\n",
    "                                  multinomial_loglike(response.shape,\n",
    "                                                      response), \n",
    "                                  None))\n",
    "            elif dtype == 'continuous':\n",
    "                response = np.squeeze(self.X[:,idx]) # it will be a 2D array\n",
    "                if var not in ['snr', 'w_surface_window_final', 'intercept']:\n",
    "                    l, u = np.percentile(response, [5, 95]) # quick and dirty cleaning..\n",
    "                    response = np.clip(response, l, u)\n",
    "                elif var == 'w_surface_window_final':\n",
    "                    l, u = np.percentile(response, [2, 98]) # quick and dirty cleaning..\n",
    "                    response = np.clip(response, l, u)\n",
    "                response -= np.mean(response)\n",
    "                response /= np.std(response)\n",
    "                self.X[:,idx] = response[:,None]\n",
    "                self.sum_sq.append((response**2).sum())\n",
    "                self.desc.append((var, dtype, idx,\n",
    "                                  gaussian_loglike(response.shape,\n",
    "                                                   response),\n",
    "                                  idx_cont))\n",
    "                idx_cont += 1\n",
    "            else:\n",
    "                self.desc.append((var, dtype, idx, None, None))\n",
    "\n",
    "        rr.smooth_atom.__init__(self,\n",
    "                                shape=(X.shape[1]**2 + idx_cont),\n",
    "                                coef=coef,\n",
    "                                offset=offset,\n",
    "                                quadratic=quadratic,\n",
    "                                initial=initial)\n",
    "        \n",
    "        self.matrix_slice = slice(0, X.shape[1]**2, None)\n",
    "        self.scale_slice = slice(X.shape[1]**2, X.shape[1]**2 + idx_cont, None)\n",
    "        self.sum_sq = np.array(self.sum_sq)\n",
    "        self._grad_buff = np.zeros((X.shape[1], \n",
    "                                    X.shape[1]))\n",
    "        \n",
    "    def smooth_objective(self, arg, mode='both', check_feasibility=False):\n",
    "        \n",
    "        arg = self.apply_offset(arg)\n",
    "        matrix_arg = arg[self.matrix_slice].reshape((self._grad_buff.shape))\n",
    "        scale_arg = arg[self.scale_slice]\n",
    "        scale_arg = np.maximum(scale_arg, 1.e-14)\n",
    "        scale_grad = np.zeros_like(scale_arg)\n",
    "        full_grad = np.zeros(self.shape)\n",
    "        eta = natural_param = self.X.dot(matrix_arg) # same shape as X\n",
    "        nobs = eta.shape[0]\n",
    "        # because we will force\n",
    "        # diagonal blocks to have np.inf\n",
    "        # weight, these parameters will be zero\n",
    "        # so column j of eta above is really only summing over k != j\n",
    "        _f = []\n",
    "        _g = []\n",
    "        for _, _, _slice, _loss, _scale_idx in self.desc:\n",
    "            if _loss is not None:\n",
    "                if _scale_idx is not None: # continuous variable\n",
    "                    _scale = scale_arg[_scale_idx]\n",
    "                    _eta = np.squeeze(eta[:,_slice])\n",
    "                    _fval, _gval = _loss.smooth_objective(_eta / \n",
    "                                                          _scale, 'both')\n",
    "                    scale_grad[_scale_idx] = 0.5 * ((- nobs / _scale) + \n",
    "                                                        self.sum_sq[_scale_idx] -\n",
    "                                                        1. / _scale**2 * (_eta**2).sum())\n",
    "                    _fval *= _scale\n",
    "                    _fval += -nobs * 0.5 * np.log(_scale)\n",
    "                else:\n",
    "                    _fval, _gval = _loss.smooth_objective(eta[:,_slice], \n",
    "                                                          'both')\n",
    "                _f.append(_fval)\n",
    "                _g.append(_reshape(_gval))\n",
    "        \n",
    "        if mode == 'func':\n",
    "            return self.scale(np.sum(_f))\n",
    "        elif mode == 'grad':\n",
    "            self._grad_buff[:,1:] = self.scale(self.X.T.dot(np.hstack(_g)))\n",
    "            self._grad_buff[:,0] = 0\n",
    "            if self.symmetrize:\n",
    "                self._grad_buff = 0.5 * (self._grad_buff + self._grad_buff.T)\n",
    "            full_grad[self.matrix_slice] = self._grad_buff.reshape(-1)\n",
    "            full_grad[self.scale_slice] = self.scale(scale_grad)\n",
    "            return full_grad\n",
    "        elif mode == 'both':\n",
    "            self._grad_buff[:,1:] = self.scale(self.X.T.dot(np.hstack(_g)))\n",
    "            self._grad_buff[:,0] = 0\n",
    "            if self.symmetrize:\n",
    "                self._grad_buff = 0.5 * (self._grad_buff + self._grad_buff.T)\n",
    "            full_grad[self.matrix_slice] = self._grad_buff.reshape(-1)\n",
    "            full_grad[self.scale_slice] = self.scale(scale_grad)\n",
    "            return self.scale(np.sum(_f)), full_grad"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/Users/jonathantaylor/Stanford/projects/CloudMask/other/regreg/regreg/smooth/mglm.py:787: RuntimeWarning: divide by zero encountered in log\n",
      "  loss_terms = np.log(saturated) * self.counts\n",
      "/Users/jonathantaylor/Stanford/projects/CloudMask/other/regreg/regreg/smooth/mglm.py:787: RuntimeWarning: invalid value encountered in multiply\n",
      "  loss_terms = np.log(saturated) * self.counts\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "(array([0.00000000e+00, 4.27455210e+37, 1.48234511e-01, 1.48234511e-01,\n",
       "        5.01065967e-02, 2.71481633e+37, 3.24797455e+37, 1.17049969e-01,\n",
       "        4.79491936e-01, 4.99880513e-01, 1.29609944e-01, 2.40016662e-01,\n",
       "        2.18420378e-01, 9.24887027e-02, 3.79471257e-02, 3.87709290e-02,\n",
       "        4.64835303e-01, 4.99214417e-01, 3.29700907e-01, 1.41454415e-01,\n",
       "        2.48590316e-01, 4.57907820e-01, 4.53777379e-01, 9.53066884e-02,\n",
       "        4.89373218e-01, 2.95966657e-01, 3.68165670e-01, 3.45703179e-01,\n",
       "        2.77489125e-01, 2.77489125e-01, 4.27455210e+37, 4.27455210e+37,\n",
       "        1.57090474e+08, 3.24797455e+37]),\n",
       " (1164,))"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "loss = full_loss(X, desc2)\n",
    "F, G = loss.smooth_objective(np.zeros(loss.shape), 'both')\n",
    "G.shape\n",
    "X.std(0), loss.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Construct penalty\n",
    "\n",
    "The basic penalty is a group lasso for every \"block\" $\\Theta[k,j]$. We've flattened\n",
    "$\\Theta$ above so we can just use the usual group LASSO penalty.\n",
    "\n",
    "The penality is\n",
    "$$\n",
    "{\\cal P}(\\Theta) = \\lambda \\sum_{(j,k): j < k} w_{(j,k)} \\|\\Theta[j,k]\\|_F\n",
    "$$\n",
    "where\n",
    "$$\n",
    "\\|A\\|_F = Tr(A^TA)^{1/2} = \\left(\\sum_{i,j} A_{ij}^2 \\right)^{1/2}\n",
    "$$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(34, 34, 2)"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "R, C = np.zeros((2, X.shape[1], X.shape[1]), np.int)\n",
    "var_names = list(D.columns) + ['intercept']\n",
    "\n",
    "for l, r in product(desc2, desc2):\n",
    "    l_slice = l[2]\n",
    "    r_slice = r[2]\n",
    "    R[l_slice][:,r_slice] = R[r_slice][:,l_slice] = var_names.index(r[0])\n",
    "    C[l_slice][:,r_slice] = C[r_slice][:,l_slice] = var_names.index(l[0])  \n",
    "I = np.transpose(np.array([R, C]), [1, 2, 0])\n",
    "I.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(slice(1, 2, None), slice(2, 4, None))"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "B2_slice, M1_slice = desc2[1][2], desc2[2][2]\n",
    "B2_slice, M1_slice"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(array([[4, 4]]),\n",
       " array([[4],\n",
       "        [4]]))"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "I[B2_slice][:,M1_slice][:,:,0], I[M1_slice][:,B2_slice][:,:,0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(array([[5, 5]]),\n",
       " array([[5],\n",
       "        [5]]))"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "I[B2_slice][:,M1_slice][:,:,1], I[M1_slice][:,B2_slice][:,:,1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1156,\n",
       " ['intercept-intercept',\n",
       "  'intercept-s_li',\n",
       "  'intercept-q_flag',\n",
       "  'intercept-q_flag',\n",
       "  'intercept-snr',\n",
       "  'h_rb-intercept',\n",
       "  'dh_fit_dx-intercept',\n",
       "  'b_snow_conf-intercept',\n",
       "  'b_snow_conf-intercept',\n",
       "  'b_snow_conf-intercept',\n",
       "  'b_snow_conf-intercept',\n",
       "  'b_snow_conf-intercept',\n",
       "  'b_snow_conf-intercept',\n",
       "  'b_snow_conf-intercept',\n",
       "  'b_snow_conf-intercept',\n",
       "  'c_flg_asr-intercept',\n",
       "  'c_flg_asr-intercept',\n",
       "  'c_flg_asr-intercept',\n",
       "  'c_flg_asr-intercept',\n",
       "  'c_flg_asr-intercept',\n",
       "  'c_flg_asr-intercept',\n",
       "  'c_flg_atm-intercept',\n",
       "  'c_flg_atm-intercept',\n",
       "  'c_flg_atm-intercept',\n",
       "  'intercept-msw',\n",
       "  'intercept-msw',\n",
       "  'intercept-msw',\n",
       "  'intercept-msw',\n",
       "  'intercept-layer_flag',\n",
       "  'intercept-layer_flag',\n",
       "  'bckgrd-intercept',\n",
       "  'e_bckgrd-intercept',\n",
       "  'intercept-n_fit_photons',\n",
       "  'intercept-w_surface_window_final',\n",
       "  'intercept-s_li',\n",
       "  's_li-s_li',\n",
       "  'q_flag-s_li',\n",
       "  'q_flag-s_li',\n",
       "  's_li-snr',\n",
       "  'h_rb-s_li'])"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "groups = ['-'.join(sorted([var_names[r], var_names[c]])) for r, c in zip(R.reshape(-1), C.reshape(-1))]\n",
    "len(groups), groups[:40]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'intercept-intercept': inf,\n",
       " 'intercept-s_li': 0.0,\n",
       " 'intercept-q_flag': 0.0,\n",
       " 'intercept-snr': 0.0,\n",
       " 'h_rb-intercept': 0.0,\n",
       " 'dh_fit_dx-intercept': 0.0,\n",
       " 'b_snow_conf-intercept': 0.0,\n",
       " 'c_flg_asr-intercept': 0.0,\n",
       " 'c_flg_atm-intercept': 0.0,\n",
       " 'intercept-msw': 0.0,\n",
       " 'intercept-layer_flag': 0.0,\n",
       " 'bckgrd-intercept': 0.0,\n",
       " 'e_bckgrd-intercept': 0.0,\n",
       " 'intercept-n_fit_photons': 0.0,\n",
       " 'intercept-w_surface_window_final': 0.0,\n",
       " 's_li-s_li': inf,\n",
       " 'q_flag-s_li': 8.960968254112539e+36,\n",
       " 's_li-snr': 2.1418325834683843e+36,\n",
       " 'h_rb-s_li': 1.1604623865936536e+75,\n",
       " 'dh_fit_dx-s_li': 1.3883636455770038e+75,\n",
       " 'b_snow_conf-s_li': 3.3809574676806117e+37,\n",
       " 'c_flg_asr-s_li': 3.465550148909536e+37,\n",
       " 'c_flg_atm-s_li': 2.785607393439636e+37,\n",
       " 'msw-s_li': 3.261399380603476e+37,\n",
       " 'layer_flag-s_li': 1.6774577114560335e+37,\n",
       " 'bckgrd-s_li': 1.8271795682356935e+75,\n",
       " 'e_bckgrd-s_li': 1.8271795682356935e+75,\n",
       " 'n_fit_photons-s_li': 6.714914151075733e+45,\n",
       " 's_li-w_surface_window_final': 1.3883636455770038e+75,\n",
       " 'q_flag-q_flag': inf,\n",
       " 'q_flag-snr': 0.0105041092401315,\n",
       " 'h_rb-q_flag': 5.691212175932136e+36,\n",
       " 'dh_fit_dx-q_flag': 6.808899776168398e+36,\n",
       " 'b_snow_conf-q_flag': 0.1658110295401608,\n",
       " 'c_flg_asr-q_flag': 0.1699596766912156,\n",
       " 'c_flg_atm-q_flag': 0.1366134990505425,\n",
       " 'msw-q_flag': 0.15994758709889528,\n",
       " 'layer_flag-q_flag': 0.08226692965097128,\n",
       " 'bckgrd-q_flag': 8.960968254112539e+36,\n",
       " 'e_bckgrd-q_flag': 8.960968254112539e+36,\n",
       " 'n_fit_photons-q_flag': 32931701.723756853,\n",
       " 'q_flag-w_surface_window_final': 6.808899776168398e+36,\n",
       " 'snr-snr': inf,\n",
       " 'h_rb-snr': 1.3603020714027367e+36,\n",
       " 'dh_fit_dx-snr': 1.6274495104337766e+36,\n",
       " 'b_snow_conf-snr': 0.03963181831433984,\n",
       " 'c_flg_asr-snr': 0.04062341960043572,\n",
       " 'c_flg_atm-snr': 0.03265308338457644,\n",
       " 'msw-snr': 0.038230350111812694,\n",
       " 'layer_flag-snr': 0.01966327582819922,\n",
       " 'bckgrd-snr': 2.1418325834683843e+36,\n",
       " 'e_bckgrd-snr': 2.1418325834683843e+36,\n",
       " 'n_fit_photons-snr': 7871269.017009796,\n",
       " 'snr-w_surface_window_final': 1.6274495104337766e+36,\n",
       " 'h_rb-h_rb': inf,\n",
       " 'dh_fit_dx-h_rb': 8.817654365311559e+74,\n",
       " 'b_snow_conf-h_rb': 2.1472842845461246e+37,\n",
       " 'c_flg_asr-h_rb': 2.2010100520918193e+37,\n",
       " 'c_flg_atm-h_rb': 1.7691707263480655e+37,\n",
       " 'h_rb-msw': 2.071351592719851e+37,\n",
       " 'h_rb-layer_flag': 1.0653723438500574e+37,\n",
       " 'bckgrd-h_rb': 1.1604623865936536e+75,\n",
       " 'e_bckgrd-h_rb': 1.1604623865936536e+75,\n",
       " 'h_rb-n_fit_photons': 4.264717839994846e+45,\n",
       " 'h_rb-w_surface_window_final': 8.817654365311559e+74,\n",
       " 'dh_fit_dx-dh_fit_dx': inf,\n",
       " 'b_snow_conf-dh_fit_dx': 2.5689858385962184e+37,\n",
       " 'c_flg_asr-dh_fit_dx': 2.6332627193920814e+37,\n",
       " 'c_flg_atm-dh_fit_dx': 2.1166151937855053e+37,\n",
       " 'dh_fit_dx-msw': 2.4781408529592e+37,\n",
       " 'dh_fit_dx-layer_flag': 1.274599029052815e+37,\n",
       " 'bckgrd-dh_fit_dx': 1.3883636455770038e+75,\n",
       " 'dh_fit_dx-e_bckgrd': 1.3883636455770038e+75,\n",
       " 'dh_fit_dx-n_fit_photons': 5.102258613545063e+45,\n",
       " 'dh_fit_dx-w_surface_window_final': 1.0549338695928474e+75,\n",
       " 'b_snow_conf-b_snow_conf': inf,\n",
       " 'b_snow_conf-c_flg_asr': 0.6412548530679474,\n",
       " 'b_snow_conf-c_flg_atm': 0.5154403148219312,\n",
       " 'b_snow_conf-msw': 0.6034794161795204,\n",
       " 'b_snow_conf-layer_flag': 0.31039167002846724,\n",
       " 'b_snow_conf-bckgrd': 3.3809574676806117e+37,\n",
       " 'b_snow_conf-e_bckgrd': 3.3809574676806117e+37,\n",
       " 'b_snow_conf-n_fit_photons': 124250727.9447928,\n",
       " 'b_snow_conf-w_surface_window_final': 2.5689858385962184e+37,\n",
       " 'c_flg_asr-c_flg_asr': inf,\n",
       " 'c_flg_asr-c_flg_atm': 0.528336803068552,\n",
       " 'c_flg_asr-msw': 0.6185786720468569,\n",
       " 'c_flg_asr-layer_flag': 0.3181577729297392,\n",
       " 'bckgrd-c_flg_asr': 3.465550148909536e+37,\n",
       " 'c_flg_asr-e_bckgrd': 3.465550148909536e+37,\n",
       " 'c_flg_asr-n_fit_photons': 127359522.51614426,\n",
       " 'c_flg_asr-w_surface_window_final': 2.6332627193920814e+37,\n",
       " 'c_flg_atm-c_flg_atm': inf,\n",
       " 'c_flg_atm-msw': 0.4972132124014969,\n",
       " 'c_flg_atm-layer_flag': 0.25573505113819817,\n",
       " 'bckgrd-c_flg_atm': 2.785607393439636e+37,\n",
       " 'c_flg_atm-e_bckgrd': 2.785607393439636e+37,\n",
       " 'c_flg_atm-n_fit_photons': 102371517.45085719,\n",
       " 'c_flg_atm-w_surface_window_final': 2.1166151937855053e+37,\n",
       " 'msw-msw': inf,\n",
       " 'layer_flag-msw': 0.2994155383651668,\n",
       " 'bckgrd-msw': 3.261399380603476e+37,\n",
       " 'e_bckgrd-msw': 3.261399380603476e+37,\n",
       " 'msw-n_fit_photons': 119856949.11349273,\n",
       " 'msw-w_surface_window_final': 2.4781408529592e+37,\n",
       " 'layer_flag-layer_flag': inf,\n",
       " 'bckgrd-layer_flag': 1.6774577114560335e+37,\n",
       " 'e_bckgrd-layer_flag': 1.6774577114560335e+37,\n",
       " 'layer_flag-n_fit_photons': 61646839.31620156,\n",
       " 'layer_flag-w_surface_window_final': 1.274599029052815e+37,\n",
       " 'bckgrd-bckgrd': inf,\n",
       " 'bckgrd-e_bckgrd': 1.8271795682356935e+75,\n",
       " 'bckgrd-n_fit_photons': 6.714914151075733e+45,\n",
       " 'bckgrd-w_surface_window_final': 1.3883636455770038e+75,\n",
       " 'e_bckgrd-e_bckgrd': inf,\n",
       " 'e_bckgrd-n_fit_photons': 6.714914151075733e+45,\n",
       " 'e_bckgrd-w_surface_window_final': 1.3883636455770038e+75,\n",
       " 'n_fit_photons-n_fit_photons': inf,\n",
       " 'n_fit_photons-w_surface_window_final': 5.102258613545063e+45,\n",
       " 'w_surface_window_final-w_surface_window_final': inf,\n",
       " 's_li-scale': 0,\n",
       " 'snr-scale': 0,\n",
       " 'h_rb-scale': 0,\n",
       " 'dh_fit_dx-scale': 0,\n",
       " 'bckgrd-scale': 0,\n",
       " 'e_bckgrd-scale': 0,\n",
       " 'n_fit_photons-scale': 0,\n",
       " 'w_surface_window_final-scale': 0}"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "weights = {}\n",
    "covs = {}\n",
    "for d in desc2:\n",
    "    X_ = X[:,d[2]] * 1.\n",
    "    X_ = X_ - X_.mean(0)\n",
    "    C_ = X_.T.dot(X_) / X_.shape[0]\n",
    "    covs[d[0]] = np.diag(C_).sum()\n",
    "    \n",
    "for l, r in product(covs.keys(), covs.keys()):\n",
    "    weights['-'.join(sorted([l, r]))] = np.sqrt(covs[l] * covs[r])\n",
    "    if l == r:\n",
    "        weights['-'.join([l, r])] = np.inf\n",
    "for d in loss.desc:\n",
    "    if d[1] == 'continuous':\n",
    "        weights[d[0]+'-scale'] = 0\n",
    "        groups.append(d[0]+'-scale')\n",
    "weights"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1164,)"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "penalty = rr.group_lasso(list(groups), weights=weights, lagrange=10 * np.sqrt(X.shape[0]))\n",
    "penalty.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "problem = rr.simple_problem(loss, penalty)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "loss.smooth_objective(problem.coefs, 'grad')\n",
    "X[:,0][:10]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "problem.coefs[:] = 0\n",
    "problem.coefs[-8:] = 1."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0    obj: 2.963970e+06    step: 3.96e-06    rel_obj_change: 2.66e-01    tol: 1.0e-05\n",
      "1    obj: 2.175321e+06    step: 3.96e-06    rel_obj_change: 5.45e-02    tol: 1.0e-05\n",
      "2    Decreasing step to 3.601558178130186e-06\n",
      "2    Decreasing step to 3.274143798300169e-06\n",
      "2    Decreasing step to 2.9764943620910623e-06\n",
      "2    obj: 2.056875e+06    step: 2.98e-06    rel_obj_change: 3.63e-02    tol: 1.0e-05\n",
      "3    Decreasing step to 2.705903965537329e-06\n",
      "3    Decreasing step to 2.4599126959430263e-06\n",
      "3    obj: 1.982153e+06    step: 2.46e-06    rel_obj_change: 2.94e-02    tol: 1.0e-05\n",
      "4    obj: 1.923835e+06    step: 2.46e-06    rel_obj_change: 2.43e-02    tol: 1.0e-05\n",
      "5    obj: 1.877017e+06    step: 2.46e-06    rel_obj_change: 2.11e-02    tol: 1.0e-05\n",
      "6    obj: 1.837412e+06    step: 2.46e-06    rel_obj_change: 1.90e-02    tol: 1.0e-05\n",
      "7    obj: 1.802490e+06    step: 2.46e-06    rel_obj_change: 1.72e-02    tol: 1.0e-05\n",
      "8    obj: 1.771536e+06    step: 2.46e-06    rel_obj_change: 1.55e-02    tol: 1.0e-05\n",
      "9    obj: 1.744018e+06    step: 2.46e-06    rel_obj_change: 1.40e-02    tol: 1.0e-05\n",
      "10    obj: 1.719556e+06    step: 2.46e-06    rel_obj_change: 1.26e-02    tol: 1.0e-05\n",
      "11    obj: 1.697830e+06    step: 2.46e-06    rel_obj_change: 1.13e-02    tol: 1.0e-05\n",
      "12    obj: 1.678594e+06    step: 2.46e-06    rel_obj_change: 1.01e-02    tol: 1.0e-05\n",
      "13    obj: 1.661616e+06    step: 2.46e-06    rel_obj_change: 9.00e-03    tol: 1.0e-05\n",
      "14    obj: 1.646668e+06    step: 2.46e-06    rel_obj_change: 7.98e-03    tol: 1.0e-05\n",
      "15    obj: 1.633523e+06    step: 2.46e-06    rel_obj_change: 7.08e-03    tol: 1.0e-05\n",
      "16    obj: 1.621960e+06    step: 2.46e-06    rel_obj_change: 6.28e-03    tol: 1.0e-05\n",
      "17    obj: 1.611778e+06    step: 2.46e-06    rel_obj_change: 5.57e-03    tol: 1.0e-05\n",
      "18    obj: 1.602794e+06    step: 2.46e-06    rel_obj_change: 4.96e-03    tol: 1.0e-05\n",
      "19    obj: 1.594848e+06    step: 2.46e-06    rel_obj_change: 4.42e-03    tol: 1.0e-05\n",
      "20    obj: 1.587802e+06    step: 2.46e-06    rel_obj_change: 3.94e-03    tol: 1.0e-05\n",
      "21    obj: 1.581538e+06    step: 2.46e-06    rel_obj_change: 3.53e-03    tol: 1.0e-05\n",
      "22    obj: 1.575957e+06    step: 2.46e-06    rel_obj_change: 3.16e-03    tol: 1.0e-05\n",
      "23    obj: 1.570973e+06    step: 2.46e-06    rel_obj_change: 2.84e-03    tol: 1.0e-05\n",
      "24    obj: 1.566515e+06    step: 2.46e-06    rel_obj_change: 2.55e-03    tol: 1.0e-05\n",
      "25    obj: 1.562523e+06    step: 2.46e-06    rel_obj_change: 2.29e-03    tol: 1.0e-05\n",
      "26    obj: 1.558945e+06    step: 2.46e-06    rel_obj_change: 2.06e-03    tol: 1.0e-05\n",
      "27    obj: 1.555735e+06    step: 2.46e-06    rel_obj_change: 1.85e-03    tol: 1.0e-05\n",
      "28    obj: 1.552856e+06    step: 2.46e-06    rel_obj_change: 1.66e-03    tol: 1.0e-05\n",
      "29    obj: 1.550273e+06    step: 2.46e-06    rel_obj_change: 1.49e-03    tol: 1.0e-05\n",
      "30    obj: 1.547956e+06    step: 2.46e-06    rel_obj_change: 1.34e-03    tol: 1.0e-05\n",
      "31    obj: 1.545877e+06    step: 2.46e-06    rel_obj_change: 1.21e-03    tol: 1.0e-05\n",
      "32    obj: 1.544013e+06    step: 2.46e-06    rel_obj_change: 1.08e-03    tol: 1.0e-05\n",
      "33    obj: 1.542341e+06    step: 2.46e-06    rel_obj_change: 9.72e-04    tol: 1.0e-05\n",
      "34    obj: 1.540842e+06    step: 2.46e-06    rel_obj_change: 8.72e-04    tol: 1.0e-05\n",
      "35    obj: 1.539498e+06    step: 2.46e-06    rel_obj_change: 7.83e-04    tol: 1.0e-05\n",
      "36    obj: 1.538292e+06    step: 2.46e-06    rel_obj_change: 7.04e-04    tol: 1.0e-05\n",
      "37    obj: 1.537209e+06    step: 2.46e-06    rel_obj_change: 6.34e-04    tol: 1.0e-05\n",
      "38    obj: 1.536235e+06    step: 2.46e-06    rel_obj_change: 5.71e-04    tol: 1.0e-05\n",
      "39    obj: 1.535358e+06    step: 2.46e-06    rel_obj_change: 5.15e-04    tol: 1.0e-05\n",
      "40    obj: 1.534567e+06    step: 2.46e-06    rel_obj_change: 4.66e-04    tol: 1.0e-05\n",
      "41    obj: 1.533852e+06    step: 2.46e-06    rel_obj_change: 4.22e-04    tol: 1.0e-05\n",
      "42    obj: 1.533205e+06    step: 2.46e-06    rel_obj_change: 3.83e-04    tol: 1.0e-05\n",
      "43    obj: 1.532618e+06    step: 2.46e-06    rel_obj_change: 3.48e-04    tol: 1.0e-05\n",
      "44    obj: 1.532085e+06    step: 2.46e-06    rel_obj_change: 3.16e-04    tol: 1.0e-05\n",
      "45    obj: 1.531600e+06    step: 2.46e-06    rel_obj_change: 2.88e-04    tol: 1.0e-05\n",
      "46    obj: 1.531158e+06    step: 2.46e-06    rel_obj_change: 2.63e-04    tol: 1.0e-05\n",
      "47    obj: 1.530756e+06    step: 2.46e-06    rel_obj_change: 2.40e-04    tol: 1.0e-05\n",
      "48    obj: 1.530388e+06    step: 2.46e-06    rel_obj_change: 2.20e-04    tol: 1.0e-05\n",
      "49    obj: 1.530052e+06    step: 2.46e-06    rel_obj_change: 2.01e-04    tol: 1.0e-05\n",
      "50    obj: 1.529744e+06    step: 2.46e-06    rel_obj_change: 1.84e-04    tol: 1.0e-05\n",
      "51    obj: 1.529462e+06    step: 2.46e-06    rel_obj_change: 1.69e-04    tol: 1.0e-05\n",
      "52    obj: 1.529203e+06    step: 2.46e-06    rel_obj_change: 1.55e-04    tol: 1.0e-05\n",
      "53    obj: 1.528966e+06    step: 2.46e-06    rel_obj_change: 1.42e-04    tol: 1.0e-05\n",
      "54    obj: 1.528749e+06    step: 2.46e-06    rel_obj_change: 1.30e-04    tol: 1.0e-05\n",
      "55    obj: 1.528549e+06    step: 2.46e-06    rel_obj_change: 1.19e-04    tol: 1.0e-05\n",
      "56    obj: 1.528367e+06    step: 2.46e-06    rel_obj_change: 1.08e-04    tol: 1.0e-05\n",
      "57    obj: 1.528202e+06    step: 2.46e-06    rel_obj_change: 9.85e-05    tol: 1.0e-05\n",
      "58    obj: 1.528051e+06    step: 2.46e-06    rel_obj_change: 8.95e-05    tol: 1.0e-05\n",
      "59    obj: 1.527914e+06    step: 2.46e-06    rel_obj_change: 8.23e-05    tol: 1.0e-05\n",
      "60    obj: 1.527789e+06    step: 2.46e-06    rel_obj_change: 7.76e-05    tol: 1.0e-05\n",
      "61    obj: 1.527670e+06    step: 2.46e-06    rel_obj_change: 7.64e-05    tol: 1.0e-05\n",
      "62    obj: 1.527553e+06    step: 2.46e-06    rel_obj_change: 7.84e-05    tol: 1.0e-05\n",
      "63    obj: 1.527434e+06    step: 2.46e-06    rel_obj_change: 8.14e-05    tol: 1.0e-05\n",
      "64    obj: 1.527309e+06    step: 2.46e-06    rel_obj_change: 8.09e-05    tol: 1.0e-05\n",
      "65    obj: 1.527186e+06    step: 2.46e-06    rel_obj_change: 7.33e-05    tol: 1.0e-05\n",
      "66    obj: 1.527074e+06    step: 2.46e-06    rel_obj_change: 6.41e-05    tol: 1.0e-05\n",
      "67    obj: 1.526976e+06    step: 2.46e-06    rel_obj_change: 5.99e-05    tol: 1.0e-05\n",
      "68    obj: 1.526884e+06    step: 2.46e-06    rel_obj_change: 5.92e-05    tol: 1.0e-05\n",
      "69    obj: 1.526794e+06    step: 2.46e-06    rel_obj_change: 5.99e-05    tol: 1.0e-05\n",
      "70    obj: 1.526703e+06    step: 2.46e-06    rel_obj_change: 6.11e-05    tol: 1.0e-05\n",
      "71    obj: 1.526609e+06    step: 2.46e-06    rel_obj_change: 6.27e-05    tol: 1.0e-05\n",
      "72    obj: 1.526514e+06    step: 2.46e-06    rel_obj_change: 6.44e-05    tol: 1.0e-05\n",
      "73    obj: 1.526416e+06    step: 2.46e-06    rel_obj_change: 6.62e-05    tol: 1.0e-05\n",
      "74    obj: 1.526314e+06    step: 2.46e-06    rel_obj_change: 6.83e-05    tol: 1.0e-05\n",
      "75    obj: 1.526210e+06    step: 2.46e-06    rel_obj_change: 6.46e-05    tol: 1.0e-05\n",
      "76    obj: 1.526112e+06    step: 2.46e-06    rel_obj_change: 6.06e-05    tol: 1.0e-05\n",
      "77    obj: 1.526019e+06    step: 2.46e-06    rel_obj_change: 6.09e-05    tol: 1.0e-05\n",
      "78    obj: 1.525926e+06    step: 2.46e-06    rel_obj_change: 6.11e-05    tol: 1.0e-05\n",
      "79    obj: 1.525833e+06    step: 2.46e-06    rel_obj_change: 6.11e-05    tol: 1.0e-05\n",
      "80    obj: 1.525740e+06    step: 2.46e-06    rel_obj_change: 6.10e-05    tol: 1.0e-05\n",
      "81    obj: 1.525647e+06    step: 2.46e-06    rel_obj_change: 6.08e-05    tol: 1.0e-05\n",
      "82    obj: 1.525554e+06    step: 2.46e-06    rel_obj_change: 6.05e-05    tol: 1.0e-05\n",
      "83    obj: 1.525462e+06    step: 2.46e-06    rel_obj_change: 6.01e-05    tol: 1.0e-05\n",
      "84    obj: 1.525370e+06    step: 2.46e-06    rel_obj_change: 5.96e-05    tol: 1.0e-05\n",
      "85    obj: 1.525279e+06    step: 2.46e-06    rel_obj_change: 5.91e-05    tol: 1.0e-05\n",
      "86    obj: 1.525189e+06    step: 2.46e-06    rel_obj_change: 5.84e-05    tol: 1.0e-05\n",
      "87    obj: 1.525100e+06    step: 2.46e-06    rel_obj_change: 5.77e-05    tol: 1.0e-05\n",
      "88    obj: 1.525012e+06    step: 2.46e-06    rel_obj_change: 5.69e-05    tol: 1.0e-05\n",
      "89    obj: 1.524925e+06    step: 2.46e-06    rel_obj_change: 5.60e-05    tol: 1.0e-05\n",
      "90    obj: 1.524839e+06    step: 2.46e-06    rel_obj_change: 5.50e-05    tol: 1.0e-05\n",
      "91    obj: 1.524756e+06    step: 2.46e-06    rel_obj_change: 5.40e-05    tol: 1.0e-05\n",
      "92    obj: 1.524673e+06    step: 2.46e-06    rel_obj_change: 5.29e-05    tol: 1.0e-05\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "93    obj: 1.524593e+06    step: 2.46e-06    rel_obj_change: 5.17e-05    tol: 1.0e-05\n",
      "94    obj: 1.524514e+06    step: 2.46e-06    rel_obj_change: 5.05e-05    tol: 1.0e-05\n",
      "95    obj: 1.524437e+06    step: 2.46e-06    rel_obj_change: 4.92e-05    tol: 1.0e-05\n",
      "96    obj: 1.524362e+06    step: 2.46e-06    rel_obj_change: 4.79e-05    tol: 1.0e-05\n",
      "97    obj: 1.524289e+06    step: 2.46e-06    rel_obj_change: 4.66e-05    tol: 1.0e-05\n",
      "98    obj: 1.524218e+06    step: 2.46e-06    rel_obj_change: 4.53e-05    tol: 1.0e-05\n",
      "99    obj: 1.524149e+06    step: 2.71e-06    rel_obj_change: 4.42e-05    tol: 1.0e-05\n",
      "100    obj: 1.524082e+06    step: 2.98e-06    rel_obj_change: 4.33e-05    tol: 1.0e-05\n",
      "101    obj: 1.524016e+06    step: 3.27e-06    rel_obj_change: 4.26e-05    tol: 1.0e-05\n",
      "102    obj: 1.523951e+06    step: 3.60e-06    rel_obj_change: 4.22e-05    tol: 1.0e-05\n",
      "103    obj: 1.523886e+06    step: 3.96e-06    rel_obj_change: 4.21e-05    tol: 1.0e-05\n",
      "104    obj: 1.523822e+06    step: 4.36e-06    rel_obj_change: 4.22e-05    tol: 1.0e-05\n",
      "105    obj: 1.523758e+06    step: 4.79e-06    rel_obj_change: 4.26e-05    tol: 1.0e-05\n",
      "106    obj: 1.523693e+06    step: 5.27e-06    rel_obj_change: 4.34e-05    tol: 1.0e-05\n",
      "107    obj: 1.523627e+06    step: 5.80e-06    rel_obj_change: 4.44e-05    tol: 1.0e-05\n",
      "108    obj: 1.523559e+06    step: 6.38e-06    rel_obj_change: 4.58e-05    tol: 1.0e-05\n",
      "109    obj: 1.523490e+06    step: 7.02e-06    rel_obj_change: 4.75e-05    tol: 1.0e-05\n",
      "110    obj: 1.523417e+06    step: 7.72e-06    rel_obj_change: 4.93e-05    tol: 1.0e-05\n",
      "111    obj: 1.523342e+06    step: 8.49e-06    rel_obj_change: 5.11e-05    tol: 1.0e-05\n",
      "112    obj: 1.523264e+06    step: 9.34e-06    rel_obj_change: 5.21e-05    tol: 1.0e-05\n",
      "113    obj: 1.523185e+06    step: 1.03e-05    rel_obj_change: 5.08e-05    tol: 1.0e-05\n",
      "114    Decreasing step to 1.0275665806050339e-05\n",
      "114    Decreasing step to 9.34151436913667e-06\n",
      "114    Decreasing step to 8.492285790124245e-06\n",
      "114    Decreasing step to 7.720259809203859e-06\n",
      "114    Decreasing step to 7.0184180083671436e-06\n",
      "114    Decreasing step to 6.380380007606493e-06\n",
      "114    Decreasing step to 5.800345461460448e-06\n",
      "114    Decreasing step to 5.273041328600407e-06\n",
      "114    Decreasing step to 4.793673935091278e-06\n",
      "114    Decreasing step to 4.357885395537525e-06\n",
      "114    Decreasing step to 3.961713995943205e-06\n",
      "114    Decreasing step to 3.601558178130186e-06\n",
      "114    Decreasing step to 3.274143798300169e-06\n",
      "114    obj: 1.523107e+06    step: 3.27e-06    rel_obj_change: 4.27e-05    tol: 1.0e-05\n",
      "115    Decreasing step to 2.9764943620910623e-06\n",
      "115    obj: 1.523042e+06    step: 2.98e-06    rel_obj_change: 3.89e-05    tol: 1.0e-05\n",
      "116    obj: 1.522983e+06    step: 2.98e-06    rel_obj_change: 3.79e-05    tol: 1.0e-05\n",
      "117    obj: 1.522925e+06    step: 2.98e-06    rel_obj_change: 3.72e-05    tol: 1.0e-05\n",
      "118    obj: 1.522869e+06    step: 2.98e-06    rel_obj_change: 3.66e-05    tol: 1.0e-05\n",
      "119    obj: 1.522813e+06    step: 2.98e-06    rel_obj_change: 3.56e-05    tol: 1.0e-05\n",
      "120    obj: 1.522759e+06    step: 2.98e-06    rel_obj_change: 3.33e-05    tol: 1.0e-05\n",
      "121    obj: 1.522708e+06    step: 2.98e-06    rel_obj_change: 2.93e-05    tol: 1.0e-05\n",
      "122    obj: 1.522663e+06    step: 2.98e-06    rel_obj_change: 2.66e-05    tol: 1.0e-05\n",
      "123    obj: 1.522623e+06    step: 2.98e-06    rel_obj_change: 2.52e-05    tol: 1.0e-05\n",
      "124    obj: 1.522584e+06    step: 2.98e-06    rel_obj_change: 2.39e-05    tol: 1.0e-05\n",
      "125    obj: 1.522548e+06    step: 2.98e-06    rel_obj_change: 2.27e-05    tol: 1.0e-05\n",
      "126    obj: 1.522513e+06    step: 2.98e-06    rel_obj_change: 2.16e-05    tol: 1.0e-05\n",
      "127    obj: 1.522481e+06    step: 2.98e-06    rel_obj_change: 2.05e-05    tol: 1.0e-05\n",
      "128    obj: 1.522449e+06    step: 2.98e-06    rel_obj_change: 1.95e-05    tol: 1.0e-05\n",
      "129    obj: 1.522420e+06    step: 2.98e-06    rel_obj_change: 1.86e-05    tol: 1.0e-05\n",
      "130    obj: 1.522391e+06    step: 2.98e-06    rel_obj_change: 1.77e-05    tol: 1.0e-05\n",
      "131    obj: 1.522364e+06    step: 2.98e-06    rel_obj_change: 1.68e-05    tol: 1.0e-05\n",
      "132    obj: 1.522339e+06    step: 2.98e-06    rel_obj_change: 1.58e-05    tol: 1.0e-05\n",
      "133    obj: 1.522315e+06    step: 2.98e-06    rel_obj_change: 1.49e-05    tol: 1.0e-05\n",
      "134    obj: 1.522292e+06    step: 2.98e-06    rel_obj_change: 1.42e-05    tol: 1.0e-05\n",
      "135    obj: 1.522270e+06    step: 2.98e-06    rel_obj_change: 1.39e-05    tol: 1.0e-05\n",
      "136    obj: 1.522249e+06    step: 2.98e-06    rel_obj_change: 1.38e-05    tol: 1.0e-05\n",
      "137    obj: 1.522228e+06    step: 2.98e-06    rel_obj_change: 1.38e-05    tol: 1.0e-05\n",
      "138    obj: 1.522207e+06    step: 2.98e-06    rel_obj_change: 1.40e-05    tol: 1.0e-05\n",
      "139    obj: 1.522186e+06    step: 2.98e-06    rel_obj_change: 1.41e-05    tol: 1.0e-05\n",
      "140    obj: 1.522164e+06    step: 2.98e-06    rel_obj_change: 1.42e-05    tol: 1.0e-05\n",
      "141    obj: 1.522143e+06    step: 2.98e-06    rel_obj_change: 1.41e-05    tol: 1.0e-05\n",
      "142    obj: 1.522121e+06    step: 2.98e-06    rel_obj_change: 1.40e-05    tol: 1.0e-05\n",
      "143    obj: 1.522100e+06    step: 2.98e-06    rel_obj_change: 1.37e-05    tol: 1.0e-05\n",
      "144    obj: 1.522079e+06    step: 2.98e-06    rel_obj_change: 1.34e-05    tol: 1.0e-05\n",
      "145    obj: 1.522059e+06    step: 2.98e-06    rel_obj_change: 1.31e-05    tol: 1.0e-05\n",
      "146    obj: 1.522039e+06    step: 2.98e-06    rel_obj_change: 1.28e-05    tol: 1.0e-05\n",
      "147    obj: 1.522019e+06    step: 2.98e-06    rel_obj_change: 1.25e-05    tol: 1.0e-05\n",
      "148    obj: 1.522000e+06    step: 2.98e-06    rel_obj_change: 1.21e-05    tol: 1.0e-05\n",
      "149    obj: 1.521982e+06    step: 2.98e-06    rel_obj_change: 1.17e-05    tol: 1.0e-05\n",
      "150    obj: 1.521964e+06    step: 2.98e-06    rel_obj_change: 1.13e-05    tol: 1.0e-05\n",
      "151    obj: 1.521947e+06    step: 2.98e-06    rel_obj_change: 1.09e-05    tol: 1.0e-05\n",
      "152    obj: 1.521930e+06    step: 2.98e-06    rel_obj_change: 1.05e-05    tol: 1.0e-05\n",
      "153    obj: 1.521914e+06    step: 2.98e-06    rel_obj_change: 1.01e-05    tol: 1.0e-05\n",
      "154    obj: 1.521899e+06    step: 2.98e-06    rel_obj_change: 9.73e-06    tol: 1.0e-05\n",
      "Success: Optimization stopped because decrease in objective was below tolerance\n",
      "FISTA used 154 of 10000 iterations\n"
     ]
    }
   ],
   "source": [
    "soln = problem.solve(start_step=1/X.shape[0], min_its=50, debug=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1.        , 1.47856496, 1.        , 1.        , 1.        ,\n",
       "       1.        , 1.        , 1.        ])"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "loss.smooth_objective(problem.coefs, 'grad')\n",
    "problem.coefs[-8:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([252416., 252416., 252416., 252416., 252416., 252416., 252416.,\n",
       "       252416.])"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "loss.sum_sq"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x1249d0730>]"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "problem.coefs[loss.matrix_slice].reshape((X.shape[1], X.shape[1]))[0]\n",
    "plt.plot(problem.solver_results)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.colorbar.Colorbar at 0x12d760580>"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "matrix_soln = problem.coefs[loss.matrix_slice].reshape((X.shape[1], X.shape[1]))\n",
    "matrix_soln = matrix_soln[1:][:,1:]\n",
    "plt.imshow(matrix_soln != 0)\n",
    "matrix_soln = np.sign(matrix_soln) * np.log(np.fabs(matrix_soln)+1)\n",
    "plt.colorbar()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 576x576 with 1 Axes>"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "f = plt.figure(figsize=(8,8))\n",
    "ax = plt.gca()\n",
    "ax.imshow(matrix_soln, cmap='RdBu', interpolation='nearest', vmin=-np.fabs(matrix_soln).max(),\n",
    "         vmax=np.fabs(matrix_soln).max())\n",
    "ylim, xlim = ax.get_ylim(), ax.get_xlim()\n",
    "ax.xaxis.set_ticks(np.cumsum([X[:,d[2]].shape[1] for d in desc2[1:]]) - 0.5)\n",
    "ax.yaxis.set_ticks(np.cumsum([X[:,d[2]].shape[1] for d in desc2[1:]]) - 0.5)\n",
    "ax.set_xticklabels([d[0] for d in desc2[1:]], rotation=270)\n",
    "ax.set_yticklabels([d[0] for d in desc2[1:]])\n",
    "ax.grid(color='gray', linewidth=1, linestyle='--')\n",
    "f"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "-1.4497660954439562"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 576x576 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "matrix_soln.min()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [],
   "source": [
    "group_keys = sorted(weights.keys())\n",
    "group_img = np.array([group_keys.index(g) for g in groups])[loss.matrix_slice].reshape((X.shape[1], X.shape[1]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.colorbar.Colorbar at 0x12d68fe50>"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.imshow(group_img)\n",
    "plt.colorbar()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(120,)"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.unique(group_img).shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "128"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(group_keys)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Regular markdown"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [],
   "source": [
    "from regreg.sklearn.base import sklearn_regression\n",
    "\n",
    "class sklearn_mixed(sklearn_regression):\n",
    "\n",
    "    \"\"\"\n",
    "\n",
    "    A simple regression mixin for sklearn\n",
    "    that allows any atom to be used as a regularizer.\n",
    "\n",
    "    \"\"\"\n",
    "\n",
    "    def __init__(self, \n",
    "                 atom_constructor, \n",
    "                 atom_params, \n",
    "                 desc,\n",
    "                 case_weights=False,\n",
    "                 offset=False,\n",
    "                 coef=1., \n",
    "                 quadratic=None,\n",
    "                 score_method='deviance',\n",
    "                 solve_args={},\n",
    "                 initial=None):\n",
    "        \n",
    "        self.desc = desc\n",
    "        self.initial = initial\n",
    "        sklearn_regression.__init__(self,\n",
    "                                    atom_constructor,\n",
    "                                    atom_params,\n",
    "                                    case_weights=case_weights,\n",
    "                                    offset=offset,\n",
    "                                    coef=coef,\n",
    "                                    score_method=score_method,\n",
    "                                    solve_args=solve_args,\n",
    "                                    initial=initial)\n",
    "        self.solve_args = solve_args\n",
    "        \n",
    "    def _loglike_factory(self, X, y):\n",
    "        loss = full_loss(X, self.desc)\n",
    "        return loss\n",
    "\n",
    "    def _saturated_score(self,\n",
    "                         predictions,\n",
    "                         response,\n",
    "                         case_weights=None):\n",
    "\n",
    "        # XXX fix these scores!!!\n",
    "        if self.score_method == 'deviance':\n",
    "            return np.random.standard_normal()\n",
    "        elif self.score_method == 'mean_deviance':\n",
    "            return np.random.standard_normal()\n",
    "        elif self.score_method == 'R2':\n",
    "            SSE = np.sum(loss(predictions))\n",
    "            SST = np.sum(loss(response.mean() * np.ones_like(response)))\n",
    "            return np.mean(loss(predictions))\n",
    "        else:\n",
    "            return np.nan\n",
    "        \n",
    "    def score(self, X, y, sample_weight=None):\n",
    "        '''\n",
    "        Parameters\n",
    "        ----------\n",
    "        X : array-like, shape = (n_samples, n_features)\n",
    "            Test samples.\n",
    "\n",
    "        y : array-like, shape = (n_samples) or (n_samples, n_outputs)\n",
    "            True values for X.\n",
    "\n",
    "        sample_weight : array-like, shape = [n_samples], optional\n",
    "            Sample weights.\n",
    "\n",
    "        Returns\n",
    "        -------\n",
    "        score : float\n",
    "        '''\n",
    "        return np.random.standard_normal() ### fix this!!!\n",
    "        predictions = X.dot(self._coefs)\n",
    "        if offset is not None:\n",
    "            predictions -= offset   # this is how offsets are incorporated\n",
    "                                    # in regreg\n",
    "        if sample_weight is not None:\n",
    "            if case_weights is not None:\n",
    "                case_weights *= sample_weight\n",
    "        return self._saturated_score(predictions, response, case_weights=case_weights)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/Users/jonathantaylor/Stanford/projects/CloudMask/other/regreg/regreg/smooth/mglm.py:787: RuntimeWarning: divide by zero encountered in log\n",
      "  loss_terms = np.log(saturated) * self.counts\n",
      "/Users/jonathantaylor/Stanford/projects/CloudMask/other/regreg/regreg/smooth/mglm.py:787: RuntimeWarning: invalid value encountered in multiply\n",
      "  loss_terms = np.log(saturated) * self.counts\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0    obj: 1.521899e+06    step: 3.96e-06    rel_obj_change: 1.45e-06    tol: 1.0e-05\n",
      "1    obj: 1.521897e+06    step: 3.96e-06    rel_obj_change: 1.42e-06    tol: 1.0e-05\n",
      "2    obj: 1.521894e+06    step: 3.96e-06    rel_obj_change: 1.80e-06    tol: 1.0e-05\n",
      "3    obj: 1.521892e+06    step: 3.96e-06    rel_obj_change: 2.14e-06    tol: 1.0e-05\n",
      "4    obj: 1.521888e+06    step: 3.96e-06    rel_obj_change: 2.46e-06    tol: 1.0e-05\n",
      "5    obj: 1.521885e+06    step: 3.96e-06    rel_obj_change: 2.75e-06    tol: 1.0e-05\n",
      "Success: Optimization stopped because decrease in objective was below tolerance\n",
      "FISTA used 5 of 10000 iterations\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/Users/jonathantaylor/opt/anaconda3/envs/icesat2/lib/python3.8/site-packages/sklearn/base.py:209: FutureWarning: From version 0.24, get_params will raise an AttributeError if a parameter cannot be retrieved as an instance attribute. Previously it would return None.\n",
      "  warnings.warn('From version 0.24, get_params will raise an '\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "sklearn_mixed(atom_constructor=<class 'regreg.atoms.group_lasso.group_lasso'>,\n",
       "              atom_params={'groups': ['intercept-intercept', 'intercept-s_li',\n",
       "                                      'intercept-q_flag', 'intercept-q_flag',\n",
       "                                      'intercept-snr', 'h_rb-intercept',\n",
       "                                      'dh_fit_dx-intercept',\n",
       "                                      'b_snow_conf-intercept',\n",
       "                                      'b_snow_conf-intercept',\n",
       "                                      'b_snow_conf-intercept',\n",
       "                                      'b_snow_conf-intercept',\n",
       "                                      'b_snow_conf-intercept...\n",
       "                    ('bckgrd', 'continuous', slice(30, 31, None)),\n",
       "                    ('e_bckgrd', 'continuous', slice(31, 32, None)),\n",
       "                    ('n_fit_photons', 'continuous', slice(32, 33, None)),\n",
       "                    ('w_surface_window_final', 'continuous',\n",
       "                     slice(33, 34, None))],\n",
       "              initial=array([0.00000000e+00, 4.43889641e-16, 1.69984571e+00, ...,\n",
       "       1.00000000e+00, 1.00000000e+00, 1.00000000e+00]),\n",
       "              solve_args={'debug': True, 'start_step': 3.961713995943205e-06})"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.model_selection import cross_validate\n",
    "sklearn_loss = sklearn_mixed(rr.group_lasso,\n",
    "                             {'groups':groups,\n",
    "                              'weights':weights,\n",
    "                              'lagrange':10 * np.sqrt(X.shape[0])},\n",
    "                             desc2,\n",
    "                             solve_args={'start_step':1/X.shape[0], 'debug':True},                             \n",
    "                             initial=problem.coefs.copy())                                    \n",
    "\n",
    "sklearn_loss.fit(X, None)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "<ipython-input-7-919b2bf20307>:53: RuntimeWarning: invalid value encountered in true_divide\n",
      "  response /= np.std(response)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0    obj: 1.070396e+06    step: 3.96e-06    rel_obj_change: 7.51e-03    tol: 1.0e-05\n",
      "1    obj: 1.062360e+06    step: 3.96e-06    rel_obj_change: 2.72e-03    tol: 1.0e-05\n",
      "2    obj: 1.059466e+06    step: 3.96e-06    rel_obj_change: 1.91e-03    tol: 1.0e-05\n",
      "3    obj: 1.057444e+06    step: 3.96e-06    rel_obj_change: 1.54e-03    tol: 1.0e-05\n",
      "4    obj: 1.055814e+06    step: 3.96e-06    rel_obj_change: 1.31e-03    tol: 1.0e-05\n",
      "5    obj: 1.054426e+06    step: 3.96e-06    rel_obj_change: 1.12e-03    tol: 1.0e-05\n",
      "6    obj: 1.053240e+06    step: 3.96e-06    rel_obj_change: 9.60e-04    tol: 1.0e-05\n",
      "7    obj: 1.052228e+06    step: 3.96e-06    rel_obj_change: 8.18e-04    tol: 1.0e-05\n",
      "8    obj: 1.051367e+06    step: 3.96e-06    rel_obj_change: 6.93e-04    tol: 1.0e-05\n",
      "9    obj: 1.050639e+06    step: 3.96e-06    rel_obj_change: 5.83e-04    tol: 1.0e-05\n",
      "10    obj: 1.050027e+06    step: 3.96e-06    rel_obj_change: 4.89e-04    tol: 1.0e-05\n",
      "11    obj: 1.049513e+06    step: 3.96e-06    rel_obj_change: 4.14e-04    tol: 1.0e-05\n",
      "12    obj: 1.049079e+06    step: 3.96e-06    rel_obj_change: 3.55e-04    tol: 1.0e-05\n",
      "13    obj: 1.048707e+06    step: 3.96e-06    rel_obj_change: 3.10e-04    tol: 1.0e-05\n",
      "14    obj: 1.048382e+06    step: 3.96e-06    rel_obj_change: 2.77e-04    tol: 1.0e-05\n",
      "15    obj: 1.048091e+06    step: 3.96e-06    rel_obj_change: 2.54e-04    tol: 1.0e-05\n",
      "16    obj: 1.047824e+06    step: 3.96e-06    rel_obj_change: 2.40e-04    tol: 1.0e-05\n",
      "17    obj: 1.047573e+06    step: 3.96e-06    rel_obj_change: 2.32e-04    tol: 1.0e-05\n",
      "18    obj: 1.047329e+06    step: 3.96e-06    rel_obj_change: 2.28e-04    tol: 1.0e-05\n",
      "19    obj: 1.047090e+06    step: 3.96e-06    rel_obj_change: 2.08e-04    tol: 1.0e-05\n",
      "20    obj: 1.046872e+06    step: 3.96e-06    rel_obj_change: 2.02e-04    tol: 1.0e-05\n",
      "21    obj: 1.046661e+06    step: 3.96e-06    rel_obj_change: 1.96e-04    tol: 1.0e-05\n",
      "22    obj: 1.046455e+06    step: 3.96e-06    rel_obj_change: 1.89e-04    tol: 1.0e-05\n",
      "23    obj: 1.046257e+06    step: 3.96e-06    rel_obj_change: 1.80e-04    tol: 1.0e-05\n",
      "24    obj: 1.046069e+06    step: 3.96e-06    rel_obj_change: 1.70e-04    tol: 1.0e-05\n",
      "25    obj: 1.045891e+06    step: 3.96e-06    rel_obj_change: 1.59e-04    tol: 1.0e-05\n",
      "26    obj: 1.045725e+06    step: 3.96e-06    rel_obj_change: 1.49e-04    tol: 1.0e-05\n",
      "27    obj: 1.045569e+06    step: 3.96e-06    rel_obj_change: 1.39e-04    tol: 1.0e-05\n",
      "28    obj: 1.045424e+06    step: 3.96e-06    rel_obj_change: 1.29e-04    tol: 1.0e-05\n",
      "29    obj: 1.045289e+06    step: 3.96e-06    rel_obj_change: 1.21e-04    tol: 1.0e-05\n",
      "30    obj: 1.045162e+06    step: 3.96e-06    rel_obj_change: 1.14e-04    tol: 1.0e-05\n",
      "31    obj: 1.045043e+06    step: 3.96e-06    rel_obj_change: 1.07e-04    tol: 1.0e-05\n",
      "32    obj: 1.044932e+06    step: 3.96e-06    rel_obj_change: 1.01e-04    tol: 1.0e-05\n",
      "33    obj: 1.044826e+06    step: 3.96e-06    rel_obj_change: 9.54e-05    tol: 1.0e-05\n",
      "34    obj: 1.044727e+06    step: 3.96e-06    rel_obj_change: 9.01e-05    tol: 1.0e-05\n",
      "35    obj: 1.044632e+06    step: 3.96e-06    rel_obj_change: 8.49e-05    tol: 1.0e-05\n",
      "36    obj: 1.044544e+06    step: 3.96e-06    rel_obj_change: 7.98e-05    tol: 1.0e-05\n",
      "37    obj: 1.044460e+06    step: 3.96e-06    rel_obj_change: 7.48e-05    tol: 1.0e-05\n",
      "38    obj: 1.044382e+06    step: 3.96e-06    rel_obj_change: 6.99e-05    tol: 1.0e-05\n",
      "39    obj: 1.044309e+06    step: 3.96e-06    rel_obj_change: 6.52e-05    tol: 1.0e-05\n",
      "40    obj: 1.044241e+06    step: 3.96e-06    rel_obj_change: 6.08e-05    tol: 1.0e-05\n",
      "41    obj: 1.044178e+06    step: 3.96e-06    rel_obj_change: 5.67e-05    tol: 1.0e-05\n",
      "42    obj: 1.044119e+06    step: 3.96e-06    rel_obj_change: 5.28e-05    tol: 1.0e-05\n",
      "43    obj: 1.044063e+06    step: 3.96e-06    rel_obj_change: 4.90e-05    tol: 1.0e-05\n",
      "44    obj: 1.044012e+06    step: 3.96e-06    rel_obj_change: 4.54e-05    tol: 1.0e-05\n",
      "45    obj: 1.043965e+06    step: 3.96e-06    rel_obj_change: 4.16e-05    tol: 1.0e-05\n",
      "46    obj: 1.043921e+06    step: 3.96e-06    rel_obj_change: 3.78e-05    tol: 1.0e-05\n",
      "47    obj: 1.043882e+06    step: 3.96e-06    rel_obj_change: 3.39e-05    tol: 1.0e-05\n",
      "48    obj: 1.043847e+06    step: 3.96e-06    rel_obj_change: 3.01e-05    tol: 1.0e-05\n",
      "49    obj: 1.043815e+06    step: 3.96e-06    rel_obj_change: 2.66e-05    tol: 1.0e-05\n",
      "50    obj: 1.043787e+06    step: 3.96e-06    rel_obj_change: 2.38e-05    tol: 1.0e-05\n",
      "51    obj: 1.043763e+06    step: 3.96e-06    rel_obj_change: 2.23e-05    tol: 1.0e-05\n",
      "52    obj: 1.043739e+06    step: 3.96e-06    rel_obj_change: 2.20e-05    tol: 1.0e-05\n",
      "53    obj: 1.043716e+06    step: 3.96e-06    rel_obj_change: 2.27e-05    tol: 1.0e-05\n",
      "54    obj: 1.043693e+06    step: 3.96e-06    rel_obj_change: 2.37e-05    tol: 1.0e-05\n",
      "55    obj: 1.043668e+06    step: 3.96e-06    rel_obj_change: 2.43e-05    tol: 1.0e-05\n",
      "56    obj: 1.043642e+06    step: 3.96e-06    rel_obj_change: 2.41e-05    tol: 1.0e-05\n",
      "57    obj: 1.043617e+06    step: 3.96e-06    rel_obj_change: 2.34e-05    tol: 1.0e-05\n",
      "58    obj: 1.043593e+06    step: 3.96e-06    rel_obj_change: 2.24e-05    tol: 1.0e-05\n",
      "59    obj: 1.043569e+06    step: 3.96e-06    rel_obj_change: 2.11e-05    tol: 1.0e-05\n",
      "60    obj: 1.043547e+06    step: 3.96e-06    rel_obj_change: 1.98e-05    tol: 1.0e-05\n",
      "61    obj: 1.043527e+06    step: 3.96e-06    rel_obj_change: 1.84e-05    tol: 1.0e-05\n",
      "62    obj: 1.043508e+06    step: 3.96e-06    rel_obj_change: 1.70e-05    tol: 1.0e-05\n",
      "63    obj: 1.043490e+06    step: 3.96e-06    rel_obj_change: 1.56e-05    tol: 1.0e-05\n",
      "64    obj: 1.043474e+06    step: 3.96e-06    rel_obj_change: 1.43e-05    tol: 1.0e-05\n",
      "65    obj: 1.043459e+06    step: 3.96e-06    rel_obj_change: 1.30e-05    tol: 1.0e-05\n",
      "66    obj: 1.043445e+06    step: 3.96e-06    rel_obj_change: 1.19e-05    tol: 1.0e-05\n",
      "67    obj: 1.043433e+06    step: 3.96e-06    rel_obj_change: 1.09e-05    tol: 1.0e-05\n",
      "68    obj: 1.043421e+06    step: 3.96e-06    rel_obj_change: 9.98e-06    tol: 1.0e-05\n",
      "Success: Optimization stopped because decrease in objective was below tolerance\n",
      "FISTA used 68 of 10000 iterations\n",
      "0    obj: 1.023744e+06    step: 3.96e-06    rel_obj_change: 1.22e-02    tol: 1.0e-05\n",
      "1    obj: 1.011290e+06    step: 3.96e-06    rel_obj_change: 3.55e-03    tol: 1.0e-05\n",
      "2    obj: 1.007698e+06    step: 3.96e-06    rel_obj_change: 2.18e-03    tol: 1.0e-05\n",
      "3    obj: 1.005497e+06    step: 3.96e-06    rel_obj_change: 1.76e-03    tol: 1.0e-05\n",
      "4    obj: 1.003725e+06    step: 3.96e-06    rel_obj_change: 1.58e-03    tol: 1.0e-05\n",
      "5    obj: 1.002140e+06    step: 3.96e-06    rel_obj_change: 1.42e-03    tol: 1.0e-05\n",
      "6    obj: 1.000714e+06    step: 3.96e-06    rel_obj_change: 1.28e-03    tol: 1.0e-05\n",
      "7    obj: 9.994310e+05    step: 3.96e-06    rel_obj_change: 1.16e-03    tol: 1.0e-05\n",
      "8    obj: 9.982733e+05    step: 3.96e-06    rel_obj_change: 1.05e-03    tol: 1.0e-05\n",
      "9    obj: 9.972229e+05    step: 3.96e-06    rel_obj_change: 9.61e-04    tol: 1.0e-05\n",
      "10    obj: 9.962644e+05    step: 3.96e-06    rel_obj_change: 8.83e-04    tol: 1.0e-05\n",
      "11    obj: 9.953848e+05    step: 3.96e-06    rel_obj_change: 8.15e-04    tol: 1.0e-05\n",
      "12    obj: 9.945736e+05    step: 3.96e-06    rel_obj_change: 7.55e-04    tol: 1.0e-05\n",
      "13    obj: 9.938230e+05    step: 3.96e-06    rel_obj_change: 7.01e-04    tol: 1.0e-05\n",
      "14    obj: 9.931267e+05    step: 3.96e-06    rel_obj_change: 6.51e-04    tol: 1.0e-05\n",
      "15    obj: 9.924801e+05    step: 3.96e-06    rel_obj_change: 6.06e-04    tol: 1.0e-05\n",
      "16    obj: 9.918791e+05    step: 3.96e-06    rel_obj_change: 5.63e-04    tol: 1.0e-05\n",
      "17    obj: 9.913204e+05    step: 3.96e-06    rel_obj_change: 5.24e-04    tol: 1.0e-05\n",
      "18    obj: 9.908007e+05    step: 3.96e-06    rel_obj_change: 4.88e-04    tol: 1.0e-05\n",
      "19    obj: 9.903171e+05    step: 3.96e-06    rel_obj_change: 4.55e-04    tol: 1.0e-05\n",
      "20    obj: 9.898666e+05    step: 3.96e-06    rel_obj_change: 4.25e-04    tol: 1.0e-05\n",
      "21    obj: 9.894464e+05    step: 3.96e-06    rel_obj_change: 3.97e-04    tol: 1.0e-05\n",
      "22    obj: 9.890538e+05    step: 3.96e-06    rel_obj_change: 3.71e-04    tol: 1.0e-05\n",
      "23    obj: 9.886865e+05    step: 3.96e-06    rel_obj_change: 3.48e-04    tol: 1.0e-05\n",
      "24    obj: 9.883428e+05    step: 3.96e-06    rel_obj_change: 3.26e-04    tol: 1.0e-05\n",
      "25    obj: 9.880210e+05    step: 3.96e-06    rel_obj_change: 3.05e-04    tol: 1.0e-05\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "26    obj: 9.877198e+05    step: 3.96e-06    rel_obj_change: 2.86e-04    tol: 1.0e-05\n",
      "27    obj: 9.874375e+05    step: 3.96e-06    rel_obj_change: 2.61e-04    tol: 1.0e-05\n",
      "28    obj: 9.871793e+05    step: 3.96e-06    rel_obj_change: 2.35e-04    tol: 1.0e-05\n",
      "29    obj: 9.869471e+05    step: 3.96e-06    rel_obj_change: 2.21e-04    tol: 1.0e-05\n",
      "30    obj: 9.867292e+05    step: 3.96e-06    rel_obj_change: 2.07e-04    tol: 1.0e-05\n",
      "31    obj: 9.865245e+05    step: 3.96e-06    rel_obj_change: 1.95e-04    tol: 1.0e-05\n",
      "32    obj: 9.863320e+05    step: 3.96e-06    rel_obj_change: 1.84e-04    tol: 1.0e-05\n",
      "33    obj: 9.861504e+05    step: 3.96e-06    rel_obj_change: 1.75e-04    tol: 1.0e-05\n",
      "34    obj: 9.859783e+05    step: 3.96e-06    rel_obj_change: 1.66e-04    tol: 1.0e-05\n",
      "35    obj: 9.858147e+05    step: 3.96e-06    rel_obj_change: 1.58e-04    tol: 1.0e-05\n",
      "36    obj: 9.856587e+05    step: 3.96e-06    rel_obj_change: 1.51e-04    tol: 1.0e-05\n",
      "37    obj: 9.855095e+05    step: 3.96e-06    rel_obj_change: 1.45e-04    tol: 1.0e-05\n",
      "38    obj: 9.853665e+05    step: 3.96e-06    rel_obj_change: 1.39e-04    tol: 1.0e-05\n",
      "39    obj: 9.852290e+05    step: 3.96e-06    rel_obj_change: 1.34e-04    tol: 1.0e-05\n",
      "40    obj: 9.850966e+05    step: 3.96e-06    rel_obj_change: 1.30e-04    tol: 1.0e-05\n",
      "41    obj: 9.849691e+05    step: 3.96e-06    rel_obj_change: 1.25e-04    tol: 1.0e-05\n",
      "42    obj: 9.848460e+05    step: 3.96e-06    rel_obj_change: 1.21e-04    tol: 1.0e-05\n",
      "43    obj: 9.847271e+05    step: 3.96e-06    rel_obj_change: 1.17e-04    tol: 1.0e-05\n",
      "44    obj: 9.846120e+05    step: 3.96e-06    rel_obj_change: 1.13e-04    tol: 1.0e-05\n",
      "45    obj: 9.845007e+05    step: 3.96e-06    rel_obj_change: 1.09e-04    tol: 1.0e-05\n",
      "46    obj: 9.843930e+05    step: 3.96e-06    rel_obj_change: 1.06e-04    tol: 1.0e-05\n",
      "47    obj: 9.842889e+05    step: 3.96e-06    rel_obj_change: 1.02e-04    tol: 1.0e-05\n",
      "48    obj: 9.841883e+05    step: 3.96e-06    rel_obj_change: 9.87e-05    tol: 1.0e-05\n",
      "49    obj: 9.840911e+05    step: 3.96e-06    rel_obj_change: 9.52e-05    tol: 1.0e-05\n",
      "50    obj: 9.839974e+05    step: 3.96e-06    rel_obj_change: 9.18e-05    tol: 1.0e-05\n",
      "51    obj: 9.839071e+05    step: 3.96e-06    rel_obj_change: 8.84e-05    tol: 1.0e-05\n",
      "52    obj: 9.838201e+05    step: 3.96e-06    rel_obj_change: 8.50e-05    tol: 1.0e-05\n",
      "53    obj: 9.837364e+05    step: 3.96e-06    rel_obj_change: 8.17e-05    tol: 1.0e-05\n",
      "54    obj: 9.836560e+05    step: 3.96e-06    rel_obj_change: 7.84e-05    tol: 1.0e-05\n",
      "55    obj: 9.835789e+05    step: 3.96e-06    rel_obj_change: 7.52e-05    tol: 1.0e-05\n",
      "56    obj: 9.835049e+05    step: 3.96e-06    rel_obj_change: 7.20e-05    tol: 1.0e-05\n",
      "57    obj: 9.834341e+05    step: 3.96e-06    rel_obj_change: 6.88e-05    tol: 1.0e-05\n",
      "58    obj: 9.833664e+05    step: 3.96e-06    rel_obj_change: 6.57e-05    tol: 1.0e-05\n",
      "59    obj: 9.833018e+05    step: 3.96e-06    rel_obj_change: 6.25e-05    tol: 1.0e-05\n",
      "60    obj: 9.832403e+05    step: 3.96e-06    rel_obj_change: 5.95e-05    tol: 1.0e-05\n",
      "61    obj: 9.831818e+05    step: 3.96e-06    rel_obj_change: 5.64e-05    tol: 1.0e-05\n",
      "62    obj: 9.831264e+05    step: 3.96e-06    rel_obj_change: 5.34e-05    tol: 1.0e-05\n",
      "63    obj: 9.830739e+05    step: 3.96e-06    rel_obj_change: 5.04e-05    tol: 1.0e-05\n",
      "64    obj: 9.830244e+05    step: 3.96e-06    rel_obj_change: 4.75e-05    tol: 1.0e-05\n",
      "65    obj: 9.829777e+05    step: 3.96e-06    rel_obj_change: 4.47e-05    tol: 1.0e-05\n",
      "66    obj: 9.829337e+05    step: 3.96e-06    rel_obj_change: 4.19e-05    tol: 1.0e-05\n",
      "67    obj: 9.828925e+05    step: 3.96e-06    rel_obj_change: 3.93e-05    tol: 1.0e-05\n",
      "68    obj: 9.828540e+05    step: 3.96e-06    rel_obj_change: 3.67e-05    tol: 1.0e-05\n",
      "69    obj: 9.828179e+05    step: 3.96e-06    rel_obj_change: 3.43e-05    tol: 1.0e-05\n",
      "70    obj: 9.827842e+05    step: 3.96e-06    rel_obj_change: 3.19e-05    tol: 1.0e-05\n",
      "71    obj: 9.827528e+05    step: 3.96e-06    rel_obj_change: 2.98e-05    tol: 1.0e-05\n",
      "72    obj: 9.827236e+05    step: 3.96e-06    rel_obj_change: 2.77e-05    tol: 1.0e-05\n",
      "73    obj: 9.826964e+05    step: 3.96e-06    rel_obj_change: 2.58e-05    tol: 1.0e-05\n",
      "74    obj: 9.826710e+05    step: 3.96e-06    rel_obj_change: 2.41e-05    tol: 1.0e-05\n",
      "75    obj: 9.826474e+05    step: 3.96e-06    rel_obj_change: 2.25e-05    tol: 1.0e-05\n",
      "76    obj: 9.826253e+05    step: 3.96e-06    rel_obj_change: 2.10e-05    tol: 1.0e-05\n",
      "77    obj: 9.826046e+05    step: 3.96e-06    rel_obj_change: 1.97e-05    tol: 1.0e-05\n",
      "78    obj: 9.825853e+05    step: 3.96e-06    rel_obj_change: 1.85e-05    tol: 1.0e-05\n",
      "79    obj: 9.825671e+05    step: 3.96e-06    rel_obj_change: 1.74e-05    tol: 1.0e-05\n",
      "80    obj: 9.825500e+05    step: 3.96e-06    rel_obj_change: 1.64e-05    tol: 1.0e-05\n",
      "81    obj: 9.825339e+05    step: 3.96e-06    rel_obj_change: 1.56e-05    tol: 1.0e-05\n",
      "82    obj: 9.825186e+05    step: 3.96e-06    rel_obj_change: 1.48e-05    tol: 1.0e-05\n",
      "83    obj: 9.825041e+05    step: 3.96e-06    rel_obj_change: 1.41e-05    tol: 1.0e-05\n",
      "84    obj: 9.824903e+05    step: 3.96e-06    rel_obj_change: 1.34e-05    tol: 1.0e-05\n",
      "85    obj: 9.824771e+05    step: 3.96e-06    rel_obj_change: 1.28e-05    tol: 1.0e-05\n",
      "86    obj: 9.824645e+05    step: 3.96e-06    rel_obj_change: 1.23e-05    tol: 1.0e-05\n",
      "87    obj: 9.824524e+05    step: 3.96e-06    rel_obj_change: 1.18e-05    tol: 1.0e-05\n",
      "88    obj: 9.824409e+05    step: 3.96e-06    rel_obj_change: 1.13e-05    tol: 1.0e-05\n",
      "89    obj: 9.824297e+05    step: 3.96e-06    rel_obj_change: 1.09e-05    tol: 1.0e-05\n",
      "90    obj: 9.824190e+05    step: 3.96e-06    rel_obj_change: 1.05e-05    tol: 1.0e-05\n",
      "91    obj: 9.824087e+05    step: 3.96e-06    rel_obj_change: 1.01e-05    tol: 1.0e-05\n",
      "92    obj: 9.823987e+05    step: 3.96e-06    rel_obj_change: 9.78e-06    tol: 1.0e-05\n",
      "Success: Optimization stopped because decrease in objective was below tolerance\n",
      "FISTA used 92 of 10000 iterations\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{'fit_time': array([ 0.64612317, 43.45547795, 58.82821488]),\n",
       " 'score_time': array([0.00000000e+00, 2.50339508e-05, 3.40938568e-05]),\n",
       " 'test_score': array([       nan, 1.77972167, 0.98073116])}"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "cross_validate(sklearn_loss, X, np.ones(X.shape[0]), cv=3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "jupytext": {
   "formats": "ipynb,Rmd"
  },
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
